package com.easyse.serviceuser.service.impl;



import com.easyse.common.utils.RedisCache;
import com.easyse.common.utils.RedisKeyUtil;

import com.easyse.easysesecurity.config.JwtUtil;
import com.easyse.model.DO.LoginUser;
import com.easyse.model.DO.User;
import com.easyse.model.vo.ResultVO;
import com.easyse.serviceuser.mapper.UserMapper;
import com.easyse.serviceuser.service.LoginService;

import com.easyse.serviceuser.util.MailClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Objects;

import static com.easyse.common.constants.UserConstant.*;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {


    // 网站域名
    @Value("${easyse.path.domain}")
    private String domain;

    // 项目名(访问路径)
    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${server.port}")
    private String port;

    @Autowired
    RedisCache redisCache;
    @Autowired
    public AuthenticationManager authenticationManager;
    @Autowired
    UserMapper userMapper;

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private MailClient mailClient;

    @Override
    public ResultVO doLogin(User user) {
    //authenticate进行用户认证
        //用户名和密码封装成authentication对象 两个参数的构造传入的是username和password
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());

        Authentication authentication =  authenticationManager.authenticate(authenticationToken);
            //认证失败给出提示信息
        if(Objects.isNull(authentication)) {
            throw new RuntimeException("认证失败!");
        }
        //认证成功 用userid生成一个jwt 存入responseResult返回
        LoginUser loginUser =   (LoginUser) authentication.getPrincipal();
        String id = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(id);

        //把完整的用户信息存入redis userid作为key 由于我们没有redis 就暂时放到缓存中
//        HashMap<String,String> map = new HashMap<>();
//        map.put("token",jwt);

        // 放到redis缓存中
        redisCache.setCacheObject(RedisKeyUtil.getUserKey(Long.parseLong(id)), jwt);
        // System.out.println("jwt:"+jwt);
        log.info(RedisKeyUtil.getUserKey(Long.parseLong(id)) + RedisKeyUtil.SPLIT + loginUser.getUser().getUsername());
        return ResultVO.success("登陆成功").data("token", jwt);

    }

    @Override
    public ResultVO doRegister(User user) {



        ResultVO resultVO;
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String pw = user.getPassword();
        //密码加密
        pw = passwordEncoder.encode(pw);
        user.setPassword(pw);
        int insert = userMapper.insert(user);
        if(insert==1){
            resultVO = ResultVO.success("注册成功, 我们已经向您的邮箱发送了一封激活邮件，请尽快激活!");
        }else{
            resultVO = ResultVO.failure("failed！插入失败，请稍后再试！");
        }


        // 给注册用户发送激活邮件
        Context context = new Context();
        context.setVariable("email", user.getEmail());
        // http://localhost:8080/activation/{{userId}}/{{code}}
        String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
        context.setVariable("url", url);
        String content = templateEngine.process( "/mail/activation1.html", context);
        mailClient.sendMail(user.getEmail(),"激活 easyse 账号", content);

        return  resultVO;
    }


    /**
     * 激活用户
     * @param userId 用户 id
     * @param code 激活码
     * @return
     */
    public int activation(Long userId, String code) {
        User user = userMapper.selectById(userId);
        if (user.getIsActived() == 1) {
            // 用户已激活
            return ACTIVATION_REPEAT;
        }
        else if (user.getActivationCode().equals(code)) {
            // 修改用户状态为已激活
            userMapper.updateStatus(userId, 1);
            return ACTIVATION_SUCCESS;
        }
        else {
            return ACTIVATION_FAILURE;
        }
    }
}
